﻿using System.Windows;
using System.Collections.Generic;
using System;

namespace Silverlight.InputCtrl
{
    public class ValidatorService : DependencyObject
    {

        #region Attached Validators
        
        public static ValidatorCollection GetValidators(DependencyObject obj)
        {
            return (ValidatorCollection)obj.GetValue(ValidatorsProperty);
        }

        public static void SetValidators(DependencyObject obj, ValidatorCollection value)
        {
            obj.SetValue(ValidatorsProperty, value);
        }

        public static readonly DependencyProperty ValidatorsProperty =
            DependencyProperty.RegisterAttached("Validators", typeof(ValidatorCollection), typeof(ValidatorService), new PropertyMetadata(null, ValidatorsPropertyCallback));

        private static void ValidatorsPropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (Common.IsInDesignMode) return;
            FrameworkElement fe = d as FrameworkElement;
            if (fe != null)
            {
                ValidatorCollection vc = e.NewValue as ValidatorCollection;
                List<Exception> exs = new List<Exception>();
                foreach (var item in vc)
                {
                    string prop = vc.PropertyToValidate == null ? "" : vc.PropertyToValidate;
                    if (!String.IsNullOrEmpty(item.PropertyToValidate))
                    {
                        prop = item.PropertyToValidate;
                    }
                    item.InitValidator(fe,prop);
                    if (item.ExceptionValidator != null)
                    {
                        exs.Add(item.ExceptionValidator);
                    }
                    ValidatorManager.RegisterValidator(item);
                }
                vc.InitCollection(fe,exs.ToArray());
            }
        }

        #endregion

        #region Attached behavior
        
        public static Behaviortrigger Getbehavior(DependencyObject obj)
        {
            return (Behaviortrigger)obj.GetValue(behaviorProperty);
        }

        public static void Setbehavior(DependencyObject obj, Behaviortrigger value)
        {
            obj.SetValue(behaviorProperty, value);
        }

        // Using a DependencyProperty as the backing store for propertyValidate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty behaviorProperty =
            DependencyProperty.RegisterAttached("behavior", typeof(Behaviortrigger), typeof(ValidatorService), new PropertyMetadata(null));

        #endregion

        #region Attached ElementErrorMessage

        public static ValidatorErrorMessage GetElementErrorMessage(DependencyObject obj)
        {
            return (ValidatorErrorMessage)obj.GetValue(ElementErrorMessageProperty);
        }

        public static void SetElementErrorMessage(DependencyObject obj, ValidatorErrorMessage value)
        {
            obj.SetValue(ElementErrorMessageProperty, value);
        }

        // Using a DependencyProperty as the backing store for propertyValidate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ElementErrorMessageProperty =
            DependencyProperty.RegisterAttached("ElementErrorMessage", typeof(ValidatorErrorMessage), typeof(ValidatorService), new PropertyMetadata(null, ElementErrorMessagePropertyCallback));

        private static void ElementErrorMessagePropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (Common.IsInDesignMode) return;

            FrameworkElement fe = d as FrameworkElement;

            if (fe != null)
            {
                ValidatorErrorMessage inf = e.NewValue as ValidatorErrorMessage;
                ValidatorManager.RegisterElementMessage(fe,inf);
                fe.Visibility = Visibility.Collapsed;
            }
        }

        #endregion

        #region Attached NewContext

        public static bool GetNewContext(DependencyObject obj)
        {
            return (bool)obj.GetValue(NewContextProperty);
        }

        public static void SetNewContext(DependencyObject obj, bool value)
        {
            obj.SetValue(NewContextProperty, value);
        }

        // Using a DependencyProperty as the backing store for propertyValidate.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NewContextProperty =
            DependencyProperty.RegisterAttached("NewContext", typeof(bool), typeof(ValidatorService), new PropertyMetadata(false, NewContextPropertyCallback));

        private static void NewContextPropertyCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (Common.IsInDesignMode) return;
            FrameworkElement fe = d as FrameworkElement;
            if (fe != null)
            {
                ValidatorManager.InitContext(fe, (bool)e.NewValue);
            }
        }

        #endregion

    }
}
